from entity import*
from hitbox import*

class moveable(entity): 
    """Moveable object"""
    def __init__(self, manager):
        entity.__init__(self, manager)
        self.updates = True

        
        self.rect = pygame.Rect(0,0,60,60) #I am making the player hitbox the same size as the draw rect. I don't fully understand why it should be smaller.
        self.rect.topleft = (60,90)

        self.lhitbox = hitbox(self.rect, -(self.rect.width / 2) - 5,15,10,(self.rect.height / 2))
        self.rhitbox = hitbox(self.rect, +(self.rect.width / 2) + 5,15,10,(self.rect.height / 2))
        self.bhitbox = hitbox(self.rect,0,(self.rect.height / 2) + 5,(self.rect.width / 1.5),5)
        self.toprhitbox = hitbox(self.rect, +(self.rect.width / 2) + 6,-23,10,10)
        self.toplhitbox	= hitbox(self.rect, -(self.rect.width / 2) - 6 ,-23,10,10)
        self.pickuphitbox = hitbox(self.rect,0,0,(self.rect.width * 2),(self.rect.height *2))

        self.right = False			#Moving right
        self.canmoveright = False	#Can move right
        self.left = False
        self.canmoveleft = False
        self.canmovedown = False #Replaces self.down
        self.canmoveup = True

        self.jump = False		#Player Presses space
        self.injump = False		#Player is in a jump (moving upward)
        self.holdjump = 0		#Variable that counts upward. Makes sure that if the player holds down space, they will not walljump after jumpin'
        self.hold = False		#Variable that, when true, adds to 'holdjump'
        self.walljumptimer = 0
        self.previouslyJumping = False #If the player was holding the jump button in the last frame.

        self.speed = 0
        self.downforce = 0
        self.jumpforce = 0
        
        self.owner = 0
        #manager.game.player = 0
        #manager.game.dog = 0
        
        self.carried = False
        self.carrytimer = 10
        
        self.C = False
        self.throwdir = 0
        
        self.thrown = 0
        

        #THESE ARE THE THINGS YOU WILL CHANGE
        self.mass = 1               #Mass goes on a scale from 0(really heavy) to 1 (light object) For some reason, if the mass is below .35 (meaning speed is less than 1), the player will not be able to push the object. Be wary.
        self.canbecarried = True    #Self explanatory. This would be changed in the level editor.
        entity.collides = False
        self.fetch = False
        self.chew = True
        #END CHANGING STUFF
        
        self.weight = self.mass * 3 #What speed the player will move while carrying/pushing
        self.collides = entity.collides
        
        #manager.quadtree.insertEntity(self)
    def delete(self,manager):
        #manager.removeEntity(self)
        pass
        
    def update(self, timeElapsed, manager):
        manager.quadtrees[int(self.layer)].removeEntity(self)
        self.move(manager)

        self.C = manager.keysdown['down']
        self.dC = manager.game.dog.carrybutton
        
        #These lines get entities near the hitboxes specified.
        entitiesnearby = manager.getEntitiesNearby(self.rect) 
        entitiesnearby.extend(manager.getEntitiesNearby(self.lhitbox.rect)) # Could consolidate by making a big rect that fits all
        entitiesnearby.extend(manager.getEntitiesNearby(self.rhitbox.rect))
        entitiesnearby.extend(manager.getEntitiesNearby(self.bhitbox.rect))
        entitiesnearby.extend(manager.getEntitiesNearby(self.toprhitbox.rect))
        entitiesnearby.extend(manager.getEntitiesNearby(self.toplhitbox.rect))
        entitiesnearby.extend(manager.getEntitiesNearby(self.pickuphitbox.rect))

        colliderects = []
        pushrects = []
        if(entitiesnearby != None):
            for entity in entitiesnearby:
                if(self.collides == True):
                    colliderects.append(entity.rect)
                if(self.collides == False):
                    if (entity != manager.game.player) and (entity != manager.game.dog):
                       colliderects.append(entity.rect) 
                if(entity == manager.game.player) or ((self.thrown != 0) and (entity == manager.game.dog)):
                    pushrects.append(entity.rect)
                    
                                  
        rHit = self.rhitbox.rect.collidelist(colliderects)
        bHit = self.bhitbox.rect.collidelist(colliderects)
        lHit = self.lhitbox.rect.collidelist(colliderects)
        toprHit = self.toprhitbox.rect.collidelist(colliderects)
        toplHit = self.toplhitbox.rect.collidelist(colliderects)

        rPush = self.lhitbox.rect.collidelist(pushrects)
        lPush = self.rhitbox.rect.collidelist(pushrects) 
        pickup = self.pickuphitbox.rect.collidelist(pushrects) 
        
        if (self.carrytimer < 10):
            self.carrytimer += 1
        
        if (pickup != -1):
            if(self.C) and (self.carrytimer == 10) and (self.canbecarried == True) and (manager.game.player.climbing == False):
                if (self.carried == False):
                    self.owner = manager.game.player
                    self.carried = True
                    self.owner.carrying = self
                    self.carrytimer = 0
            if ((self.fetch == True) or (self.chew == True)):
                if(self.dC) and (self.carrytimer == 10) and (self.canbecarried == True):
                    if (self.carried == False):
                        self.owner = manager.game.dog
                        self.carried = True
                        self.owner.carrying = self
                        self.carrytimer = 0
        if (rPush != -1) and (self.collides == True):
            if (self.canmoveright == True) and (manager.game.player.right == True):
                manager.game.player.speed = self.weight
                self.right = True
        else:
            self.right = False
        if (lPush != -1) and (self.collides == True):
            if (self.canmoveleft == True) and (manager.game.player.left == True):
                manager.game.player.speed = -self.weight
                self.left = True
        else:
            self.left = False
            
        if (self.carried == True) and (self.carrytimer == 10):
            if(self.C) and (self.owner == manager.game.player):
                self.carried = False
                self.carrytimer = 0
                manager.game.player.carrying = 0
            if(self.dC) and (self.owner == manager.game.dog):
                self.carried = False
                self.carrytimer = 0
                manager.game.dog.carrying = 0
        
        if(rHit != -1):
            self.canmoveright = False
            if self.speed > 0:
                self.speed -= 1
        else:
            self.canmoveright = True

        if(lHit != -1):
            self.canmoveleft = False
            if self.speed < 0:
                self.speed += 1
        else:
            self.canmoveleft = True

        if(bHit != -1):
            self.canmovedown = False
            self.downforce = 0
        else:
            self.canmovedown = True

        if(toprHit == -1) and (rHit != -1) and (self.right == True):		#Conditions for climbing up an edge on right side
            if self.jumpforce < 5:
                self.jumpforce += 1
            self.speed = 1
            self.canmovedown = False
            self.injump = True

        if(toplHit == -1) and (lHit != -1) and (self.left == True):			#Conditions for climbing up an edge on left side
            if self.jumpforce < 5:
                self.jumpforce += 1
            self.speed = -1
            self.canmovedown = False
            self.injump = True
                    
        if (toprHit != -1) and (toplHit != -1):
            self.canmoveup = False
        else:
            self.canmoveup = True
            
        if(self.canmoveup != True):     #Can I move up?
            self.jumpforce = 0
                
                
        if (self.thrown == 2):
            if (self.fetch == True):
                manager.game.dog.setfetch(self)
            elif(self.chew == True):
                manager.game.dog.setfetch(self)
                manager.game.dog.setchew()
            self.thrown = 3
            
        
        
        manager.quadtrees[int(self.layer)].insertEntity(self)


    def draw(self, camera, screen, manager):
        entity.draw(self, camera, screen, manager)
        """self.pickuphitbox.draw(camera, screen)
        self.rhitbox.draw(camera, screen)
        self.bhitbox.draw(camera, screen)
        self.toprhitbox.draw(camera, screen)
        self.toplhitbox.draw(camera, screen)"""

    def move(self, manager):
        self.moveBy(self.speed,0)
        
        self.lhitbox.update()
        self.rhitbox.update()
        self.bhitbox.update()
        self.toprhitbox.update()
        self.toplhitbox.update()#Adjust hitboxes after move
        self.pickuphitbox.update()

        if (self.carried == False):
            if (self.carrytimer < 9): #This makes the player 'Throw' the object they are dropping
                if (self.throwdir == 1):
                    self.speed = 6
                    if (manager.game.player.speed > .2):
                        self.speed = 10
                        if (self.mass == 1):
                            self.jumpforce += .5
                            self.injump = True
                            self.canmovedown = False
                            if (self.fetch == True) or (self.chew == True):
                                self.thrown = 1
                if (self.throwdir == 0):
                    self.speed = -6
                    if (manager.game.player.speed < 0):
                        self.speed = -10
                        if (self.mass == 1):
                            self.jumpforce += .5
                            self.injump = True
                            self.canmovedown = False
                            if (self.fetch == True) or (self.chew == True):
                                self.thrown = 1
            if (self.carrytimer == 9):
                self.speed = self.speed / 3
        
            #If on ground, handle like this.
            if self.injump == False and self.canmovedown == False:
                if self.canmoveright == True:
                    if self.right == True:
                        self.speed = self.weight
                        
                if self.canmoveleft == True:
                    if self.left == True:
                        self.speed =  self.mass * -3
                            
                if self.left == False and self.right == False:
                    if self.speed > 0:
                        self.speed -= .5
                    if self.speed < 0:
                        self.speed += .5
                        
                if (self.thrown == 1):
                    self.thrown = 2
            
            #If in air, handle like tihs.
            if self.injump == True or self.canmovedown == True:
                if self.canmoveright == True:
                    if self.right == True:
                        self.speed =  self.weight
                if self.canmoveleft == True:
                    if self.left == True:
                        self.speed =  self.mass * -3
                
            #If falling, apply downforce that grows with time and stops at 4.5
            if self.canmovedown == True and self.injump == False:
                if self.downforce < 3 / self.mass:
                    self.downforce += .2
                    self.walljumptimer = 20
                self.rect.move_ip(0,self.downforce / manager.fpsupdate)
                self.lhitbox.update()
                self.rhitbox.update()
                self.bhitbox.update()
                self.toprhitbox.update()
                self.toplhitbox.update()
                

            #If not jumping, activate jump!
            if self.injump == False and self.canmovedown == False:
                if self.jump == True:
                    self.injump = True
                    
            #If jumping, apply these forces:
            if self.injump == True:
                if self.jumpforce > 0:
                    self.canmovedown == False
                    self.rect.move_ip(0,-self.jumpforce / manager.fpsupdate)	
                    self.jumpforce -= .2
                    self.lhitbox.update()
                    self.rhitbox.update()
                    self.bhitbox.update()
                    self.toprhitbox.update()
                    self.toplhitbox.update()
                    
            #If there is no jumpforce left, take the object out of jump mode.
            if self.jumpforce <= 0:
                    self.injump = False
            
            #These two If statements make it so you slide slower while going up or down a wall
            if (self.canmoveright == False or self.canmoveleft == False) and self.injump == True:
                self.jumpforce -= .05
            if (self.canmoveright == False or self.canmoveleft == False) and self.canmovedown == True:
                if self.downforce > .15:
                    self.downforce -= .15
            
            #Holdin jump key
            if self.hold == True:
                self.holdjump = 1
            else:
                self.holdjump = 0
                
        #Carried?
        elif (self.carried == True):
            if (self.fetch == True) or (self.chew == True):
                self.thrown = 0
            if (self.carrytimer < 10):  #This makes the 'pick up' animation smoother
                if (self.rect.left + (self.rect.width / 2) < (self.owner.rect.left + (self.owner.rect.width / 2))):
                    self.rect.move_ip(5 / manager.fpsupdate,0)
                if (self.rect.left + (self.rect.width / 2) > (self.owner.rect.left + (self.owner.rect.width / 2))):
                    self.rect.move_ip(-5 / manager.fpsupdate,0)
                if ((self.rect.bottom - (self.rect.height / 2)) >(self.owner.rect.top - (self.rect.height / 2))):
                    self.rect.move_ip(0, -5 / manager.fpsupdate)
            else:
                self.rect.center = (self.owner.rect.left + (self.owner.rect.width / 2), self.owner.rect.top - (self.rect.height / 2))
                if (self.owner.speed > self.weight):
                    self.owner.speed = self.weight
                    
                elif (self.owner.speed < -self.weight):
                    self.owner.speed = -self.weight
                    
                if self.owner.speed > .4:
                    self.throwdir = 1
                if self.owner.speed < -.4:
                    self.throwdir = 0
